Ring_buffer.c
#include <stdlib.h>
#include <string.h>
#include "Ring_buffer.h"
/*********************************
typedef struct
{
uint8_t* samples;
uint16_t buffer_size;
uint16_t head;
uint16_t tail;
uint16_t bytes_avail;
unsigned long samples_taken_total;
my_bool lock;
} queue_t;
*********************************/
void init_buffer(queue_t* Buffer, uint16_t samples_amount)
{
Buffer->samples = (uint8_t*)malloc(samples_amount);
Buffer->buffer_size = samples_amount;
Buffer->bytes_written = 0;
Buffer->samples_taken_total = 0;
Buffer->lock = 0;
}
/* Function to find the lesser value between two arguments
*/
uint16_t min_val(uint16_t a, uint16_t b)
{
return a < b ? a : b; // if a is smaller than b - return a. Otherwise b
}
/* inserting a sample into the buffer.
* Arguments:
* Buffer - pointer to the Buffer (ring Buffer) we are working with
* data - pointer to the data to be inserted
* Size - amount of bytes to be inserted (max 255 - uint8_t)
*/
my_bool put_sample(queue_t* Buffer, volatile uint8_t* data, uint8_t Size)
{
if(Buffer->lock == 0)
{
Buffer->lock = 1; // Lock out the buffer to prevent interrupting by other instances during writing
if((Buffer->buffer_size - Buffer->bytes_written) < Size) // Checking if there still any free space in the buffer
{
Buffer->lock = 0;
return LOW; // if it's false then the buffer is overflown
}
const uint8_t part1 = min_val(Size, (Buffer->buffer_size - Buffer->tail));
const uint8_t part2 = Size - part1;
memcpy((void*)(Buffer->samples + Buffer->tail), (const void*)data, part1);
memcpy((void*)Buffer->samples, (const void*)(data + part1), part2);
Buffer->tail = (Buffer->tail + Size) % Buffer->buffer_size;
Buffer->bytes_written += Size;
Buffer->samples_taken_total += Size; // controlling how many data samples have been taken
Buffer->lock = 0;
return HIGH;
}
else
return LOW; // so far there is no noticing if the buffer was locked by the last writing try
}
/* Getting data out of the ring Buffer
* Arguments:
* Buffer - pointer to the Buffer (ring Buffer) we are working with
* data - pointer to the variable where the readed data will be stored
* Size - amount of bytes to be readed (max 255 - uint8_t)
*/
my_bool get_sample(queue_t* Buffer, uint8_t* data, uint8_t Size)
{
if(Buffer->lock == 0)
{
Buffer->lock = 1; // Lock out the buffer to prevent interrupting by other instances during writing
if(Buffer->bytes_written < Size) // if we want to read more than available - return LOW
{
Buffer->lock = 0;
return LOW;
}
const uint8_t part1 = min_val(Size, Buffer->buffer_size - Buffer->head);
const uint8_t part2 = Size - part1;
memcpy(data, Buffer->samples + Buffer->head, part1);
memcpy(data + part1, Buffer->samples, part2);
Buffer->head = (Buffer->head + Size) % Buffer->buffer_size;
Buffer->bytes_written -= Size;
Buffer->lock = 0;
return HIGH;
}
else
return LOW;
}